package com.njiandan.johnson.vr360library;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;

import com.njiandan.johnson.vr360library.constant.AdjustingMode;
import com.njiandan.johnson.vr360library.filters.base.AbsFilter;
import com.njiandan.johnson.vr360library.filters.base.DrawImageFilter;
import com.njiandan.johnson.vr360library.filters.base.FilterGroup;
import com.njiandan.johnson.vr360library.filters.base.OESFilter;
import com.njiandan.johnson.vr360library.filters.base.OrthoFilter;
import com.njiandan.johnson.vr360library.filters.base.vr.Sphere2DPlugin;
import com.njiandan.johnson.vr360library.utils.BitmapUtils;
import com.njiandan.johnson.vr360library.utils.StatusHelper;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

/**
 * author：johnsonZhang on 2017/3/21 16:48
 * email：15915356@qq.com
 */
public class VrRender implements GLSurfaceView.Renderer {
    public final static String TAG = "VrRender";

    private StatusHelper statusHelper;
    private VrMediaPlayerWrapper vrMediaPlayerWrapper;
    private Sphere2DPlugin spherePlugin;
    private FilterGroup filterGroup;
    private AbsFilter firstPassFilter;
    private int width, height;

    private boolean imageMode;
    private boolean planeMode;
    private boolean saveImg;

    private OrthoFilter orthoFilter;

    private VrRender() {

    }

    public VrRender init() {
        saveImg = false;
        filterGroup = new FilterGroup();

        if (!imageMode) {
            firstPassFilter = new OESFilter(statusHelper.getContext());
        } else {
            firstPassFilter = new DrawImageFilter(
                    statusHelper.getContext(),
                    "filter/imgs/texture_360_n.jpg",
                    AdjustingMode.ADJUSTING_MODE_STRETCH);
        }
        filterGroup.addFilter(firstPassFilter);
        spherePlugin = new Sphere2DPlugin(statusHelper);
        if (!planeMode) {
            filterGroup.addFilter(spherePlugin);
        } else {
            //TODO: this should be adjustable
            orthoFilter = new OrthoFilter(statusHelper,
                    AdjustingMode.ADJUSTING_MODE_FIT_TO_SCREEN);
            if (vrMediaPlayerWrapper != null) {
                vrMediaPlayerWrapper.setVideoSizeCallback(new VrMediaPlayerWrapper.VideoSizeCallback() {
                    @Override
                    public void notifyVideoSizeChanged(int width, int height) {
                        orthoFilter.updateProjection(width, height);
                    }
                });
                filterGroup.addFilter(orthoFilter);
            }
        }
        return this;
    }

    @Override
    public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
        filterGroup.init();
        if (!imageMode)
            vrMediaPlayerWrapper.setSurface(((OESFilter) firstPassFilter).getGlOESTexture().getTextureId());
    }


    @Override
    public void onDrawFrame(GL10 glUnused) {
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);

        GLES20.glFrontFace(GLES20.GL_CW);
        GLES20.glCullFace(GLES20.GL_BACK);
        GLES20.glEnable(GLES20.GL_CULL_FACE);

        if (!imageMode) {
            vrMediaPlayerWrapper.doTextureUpdate(((OESFilter) firstPassFilter).getSTMatrix());
            filterGroup.onDrawFrame(((OESFilter) firstPassFilter).getGlOESTexture().getTextureId());
        } else {
            //don't change the value, may cause crash
            filterGroup.onDrawFrame(0);
        }
        if (saveImg) {
            BitmapUtils.sendImage(width, height, statusHelper.getContext());
            saveImg = false;
        }

        GLES20.glDisable(GLES20.GL_CULL_FACE);
        //GLES20.glFinish();
    }

    @Override
    public void onSurfaceChanged(GL10 glUnused, int width, int height) {
        this.width = width;
        this.height = height;

        GLES20.glViewport(0, 0, width, height);
        filterGroup.onFilterChanged(width, height);
    }

    public void saveImg() {
        saveImg = true;
    }

    public Sphere2DPlugin getSpherePlugin() {
        return spherePlugin;
    }

    public FilterGroup getFilterGroup() {
        return filterGroup;
    }

    public VrRender setStatusHelper(StatusHelper statusHelper) {
        this.statusHelper = statusHelper;
        return this;
    }

    public VrRender setVrMediaPlayerWrapper(VrMediaPlayerWrapper vrMediaPlayerWrapper) {
        this.vrMediaPlayerWrapper = vrMediaPlayerWrapper;
        return this;
    }

    public VrRender setImageMode(boolean imageMode) {
        this.imageMode = imageMode;
        return this;
    }

    public VrRender setPlaneMode(boolean planeMode) {
        this.planeMode = planeMode;
        return this;
    }

    public static VrRender newInstance() {
        return new VrRender();
    }
}
